package com.thingple.rodbell.packet;

import android.util.Log;

import com.thingple.rodbell.cmd.Cmd;
import com.thingple.rodbell.model.PacketTagInfo;
import com.thingple.util.Bytes;

public abstract class CmdHandler extends PacketHandler {

    private static final String TAG = CmdHandler.class.getName();

    @Override
    protected void handleLogic(byte[] packetBody) {

        if (packetBody == null || packetBody.length < 1) {
            return;
        }
        if (!calcSum(packetBody)) {
            return;
        }
        byte cmd = packetBody[1];

        switch (cmd) {
            case Cmd.CMD_TAG:
            case Cmd.CMD_TAG_A: // 目前只支持 0x8A
                handleCmdTag(packetBody);
                break;
            case Cmd.CMD_CARRY_STATE:
                handleCmdCarryState(packetBody);
                break;
            case Cmd.OFFLINE_INV_STARTED_RESP:
                handleCmdOffLineInvStart();
                break;
            case Cmd.OFFLINE_INV_STOPPED_RESP:
                handleCmdOffLineInvStop();
                break;
            case Cmd.ONLINE_INV_START_RESP:
                handleCmdOnLineInvStart();
                break;
            case Cmd.ONLINE_INV_STOP_RESP:
                handleCmdOnLineInvStop();
                break;
            case Cmd.CMD_NO_TAG:
                handleNoTag(packetBody);
                break;
            default:
                if (debug) {
                    Log.d(TAG, "unknown cmd:" + Bytes.byteToHex(cmd));
                }
        }
    }

    /**
     * Address	Cmd   AntID   PC       EPC	    RSSI	Check
     * 1 Byte	0x8A  1 Byte  2 Bytes  N Bytes	1 Byte	1 Byte
     */
    private void handleCmdTag(byte[] packetBody) {
        int ant = packetBody[2] & 0x03;

        System.arraycopy(packetBody, 3, pcRaw, 0, 2);
        String pc = Bytes.byteToHex(pcRaw);
        int size = (pcRaw[0] >> 3) * 2;

        byte[] epcRaw = new byte[size];
        if (packetBody.length < (size + 5)) {
            Log.d(TAG, "bad tag:" + packetBody.length + ", need:" + size + 5);
            return;
        }
        // 第五个byte开始
        System.arraycopy(packetBody, 5, epcRaw, 0, epcRaw.length);

        String epc = Bytes.byteToHex(epcRaw);
        PacketTagInfo tag = new PacketTagInfo();
        tag.antId = ant;
        tag.epc = epc;
        tag.pc = pc;
        tag.rssi = 0; // TODO dummy
        onTag(tag);
    }
    private void handleNoTag(byte[] body) {
        Log.d(TAG, "no_tag:" + Bytes.byteToHex(body));
    }

    private void handleCmdCarryState(byte[] packetBody) {
        int state = packetBody[2] & 0xFF;
        onState(state);
    }

    /**
     * 离线盘点开始RESP
     */
    private void handleCmdOffLineInvStart() {
        Log.d(TAG, "offline inventory stared");
        this.onInventoryStatus(1);
    }

    /**
     * 离线盘点结束RESP
     */
    private void handleCmdOffLineInvStop() {
        Log.d(TAG, "offline inventory stopped");
        this.onInventoryStatus(0);
    }

    /**
     * 实时盘点开始RESP
     */
    private void handleCmdOnLineInvStart() {
        Log.d(TAG, "online inventory stared");
        onInventoryStatus(1);
    }

    /**
     * 实时盘点结束RESP
     */
    private void handleCmdOnLineInvStop() {
        Log.d(TAG, "online inventory stopped");
        onInventoryStatus(0);
    }

    abstract protected void onState(final int state);
    abstract protected void onTag(final PacketTagInfo tag);

    abstract protected void onInventoryStatus(final int state);
}
